package mylab.starters.mybatis.support.datascope;

import cn.hutool.core.lang.Assert;
import mylab.common.context.UserContext;
import mylab.usm.api.enums.DataScopeType;
import mylab.usm.api.model.account.User;
import mylab.usm.api.model.authorization.DataPermission;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.statement.select.SelectItem;

import java.util.List;

/**
 * @Description:
 * @author: Sylar
 * @date: 2021年11月25日 2:56 下午
 */
public class DefaultDataScopeHandler implements DataScopeHandler {

    @Override
    public boolean needDataScope(String mappedStatementId) {
        return getDataPermission(mappedStatementId) != null;
    }

    @Override
    public List<SelectItem> getSelectItems(String mappedStatementId, List<SelectItem> selectItems) {
        DataPermission dataPermission = getDataPermission(mappedStatementId);
        Assert.notNull(dataPermission);
        DataScopeUtil.fieldFilter(selectItems, dataPermission);
        return selectItems;
    }

    @Override
    public Expression getSqlSegment(String mappedStatementId, Expression where) {
        DataPermission dataPermission = getDataPermission(mappedStatementId);
        Assert.notNull(dataPermission);
        DataScopeType scopeType = dataPermission.getDataScopeType();
        User user = getUser();
        Assert.notNull(user);

        switch (scopeType) {
            case SELF:
                return DataScopeUtil.byUser(user.getId());
            case THIS_LEVEL:
                return DataScopeUtil.byOrg(user.getDepartmentList());
            case THIS_LEVEL_AND_BRANCH:
                return DataScopeUtil.byOrg(user.getNestedDepartmentList());
            default:
                return null;
        }
    }

    DataPermission getDataPermission(String mappedStatementId) {
        User user = getUser();
        if (user != null && user.getDataPermissionMap() != null) {
            return user.getDataPermissionMap().get(mappedStatementId);
        }
        return null;
    }

    User getUser() {
        return UserContext.getUser();
    }

}
